<?php
/**
 * 获取备份文件名
 * @param $filepath
 * @return string
 */
function file_backname($filepath)
{
    $filepre = file_pre($filepath);
    $fileext = file_ext($filepath);
    $s = "$filepre.backup.$fileext";
    return $s;
}


/**
 * 判断是否为备份文件
 * @param $filepath
 * @return bool
 */
function is_backfile($filepath)
{
    return strpos($filepath, '.backup.') !== FALSE;
}

/**
 * 生成备份文件
 * @param $filepath
 * @return bool
 */
function file_backup($filepath)
{
    $backfile = file_backname($filepath);
    if (is_file($backfile)) return TRUE;
    $r = file_copy($filepath, $backfile);
    clearstatcache();
    return $r && filesize($backfile) == filesize($filepath);
}

/**
 * 从备份文件还原
 * @param string $filepath 原始文件名
 * @return bool
 */
function file_backup_restore($filepath)
{
    $backfile = file_backname($filepath);
    $r = file_copy($backfile, $filepath);
    clearstatcache();
    $r && filesize($backfile) == filesize($filepath) && file_unlink($backfile);
    return $r;
}

/**
 * 删除备份文件
 * @param string $filepath 原始文件名
 * @return bool
 */
function file_backup_unlink($filepath)
{
    $backfile = file_backname($filepath);
    $r = file_unlink($backfile);
    return $r;
}

/**
 * 读取文件，带失败重试
 * @param $file
 * @param int $times
 * @return bool|false|string
 */
function file_get_contents_try($file, $times = 3)
{
    while ($times-- > 0) {
        $fp = fopen($file, 'rb');
        if ($fp) {
            $size = filesize($file);
            if ($size == 0) return '';
            $s = fread($fp, $size);
            fclose($fp);
            return $s;
        } else {
            sleep(1);
        }
    }
    return FALSE;
}


/**
 * 文件写入，带失败重试
 * @param $file
 * @param $s
 * @param int $times
 * @return bool|false|int
 */
function file_put_contents_try($file, $s, $times = 3)
{
    while ($times-- > 0) {
        $fp = fopen($file, 'wb');
        if ($fp and flock($fp, LOCK_EX)) {
            $n = fwrite($fp, $s);
            version_compare(PHP_VERSION, '5.3.2', '>=') and flock($fp, LOCK_UN);
            fclose($fp);
            clearstatcache();
            return $n;
        } else {
            sleep(1);
        }
    }
    return FALSE;
}

/**
 *
 * 获取文件扩展名
 * @param $filename
 * @param int $max
 * @return false|string|string[]
 */
function file_ext($filename, $max = 16)
{
    $ext = strtolower(substr(strrchr($filename, '.'), 1));
    $ext = safe_urlencode($ext);
    strlen($ext) > $max and $ext = substr($ext, 0, $max);
    if (!preg_match('#^\w+$#', $ext)) $ext = 'attach';
    return $ext;
}

/**
 * 获取文件名（不含扩展名）
 * @param $filename
 * @param int $max
 * @return false|string
 */
function file_pre($filename, $max = 32)
{
    return substr($filename, 0, strrpos($filename, '.'));
}

/**
 * 文件名，带扩展
 * @param $path
 * @return false|string
 */
function file_name($path)
{
    $start = 0;
    if (strrpos($path, '/') !== false) {
        $start = strrpos($path, '/') + 1;
    }
    return substr($path, $start);
}

/**
 * 删除文件夹，包括文件
 * @param $dir
 * @param int $keepdir
 * @return bool
 */
function rmdir_recusive($dir, $keepdir = 0)
{
    if ($dir == '/' || $dir == './' || $dir == '../') return FALSE;
    if (!is_dir($dir)) return FALSE;
    substr($dir, -1) != '/' and $dir .= '/';
    $files = glob($dir . '*');
    foreach (glob($dir . '.*') as $v) {
        if (substr($v, -1) != '.' && substr($v, -2) != '..') $files[] = $v;
    }
    $filearr = $dirarr = array();
    if ($files) {
        foreach ($files as $file) {
            if (is_dir($file)) {
                $dirarr[] = $file;
            } else {
                $filearr[] = $file;
            }
        }
    }
    if ($filearr) {
        foreach ($filearr as $file) {
            file_unlink($file);
        }
    }
    if ($dirarr) {
        foreach ($dirarr as $file) {
            rmdir_recusive($file);
        }
    }
    if (!$keepdir) file_rmdir($dir);
    return TRUE;
}

/**
 * 文件复制
 * @param $src
 * @param $dest
 * @return bool
 */
function file_copy($src, $dest)
{

    $r = is_file($src) ? copy($src, $dest) : FALSE;
    return $r;
}

/**
 * 创建文件夹
 * @param $dir
 * @param null $mod
 * @param null $recusive
 * @return bool
 */
function file_mkdir($dir, $mod = NULL, $recusive = NULL)
{
    $r = !is_dir($dir) ? mkdir($dir, $mod, $recusive) : FALSE;
    return $r;
}

/**
 * 删除文件夹，必须为空文件夹
 * @param $dir
 * @return bool
 */
function file_rmdir($dir)
{
    $r = is_dir($dir) ? rmdir($dir) : FALSE;
    return $r;
}

/**
 * 文件删除
 * @param $file
 * @return bool
 */
function file_unlink($file)
{
    $r = is_file($file) ? unlink($file) : FALSE;
    return $r;
}

/**
 * 文件修改时间
 * @param $file
 * @return false|int
 */
function file_modifitime($file)
{
    return is_file($file) ? filemtime($file) : 0;
}

/**
 * 复制文件或目录，包含子目录及文件
 * @param $src
 * @param $dst
 */
function file_copy_recusive($src, $dst)
{
    substr($src, -1) == '/' and $src = substr($src, 0, -1);
    substr($dst, -1) == '/' and $dst = substr($dst, 0, -1);
    $dir = opendir($src);
    !is_dir($dst) and mkdir($dst);
    while (FALSE !== ($file = readdir($dir))) {
        if (($file != '.') && ($file != '..')) {
            if (is_dir($src . '/' . $file)) {
                file_copy_recusive($src . '/' . $file, $dst . '/' . $file);
            } else {
                file_copy($src . '/' . $file, $dst . '/' . $file);
            }
        }
    }
    closedir($dir);
}

/**
 * 是否可写入
 * @param $file
 * @return bool
 */
function file_is_writable($file)
{
    if (PHP_OS != 'WINNT') {
        return is_writable($file);
    } else {
        if (is_file($file)) {
            $fp = fopen($file, 'a+');
            if (!$fp) return FALSE;
            fclose($fp);
            return TRUE;
        } elseif (is_dir($file)) {
            $tmpfile = $file . uniqid() . '.tmp';
            $r = touch($tmpfile);
            if (!$r) return FALSE;
            if (!is_file($tmpfile)) return FALSE;
            file_unlink($tmpfile);
            return TRUE;
        } else {
            return FALSE;
        }
    }
}

/**
 * base64数据解码写入文件
 * @param $data
 * @return false|string
 */
function file_base64_decode_save($filename, $data)
{
    if (substr($data, 0, 5) == 'data:') {
        $data = substr($data, strpos($data, ',') + 1);
    }
    $data = base64_decode($data);
    if ($filename) {
        return file_put_contents($filename, $data);
    }
    return false;
}


/*
* 列出目录下的所有匹配文件，不含子目录
* @param string $dir
* @param string $pattern
* @return array $files
*/
/**
 * @param $dir
 * @param string $pattern 模式匹配，可包含*?等
 * @return array|false
 */
function ls($dir, $pattern = '')
{
    $files = array();
    $dir = realpath($dir);
    if (is_dir($dir)) $files = glob($dir . DIRECTORY_SEPARATOR . '*' . $pattern);
    return empty($files) ? array() : $files;
}

/**
 * 获取目录下的文件名
 * @param $dirName
 * @return array
 */
function file_getlist($dirName, $subDir = false)
{
    if (!$subDir) {
        $ret = array();
        if (file_exists($dirName) && $file_list = scandir($dirName)) {
            foreach ($file_list as $item) {
                if ($item != "." && $item != "..") {
                    $ret[] = $item;
                }
            }
        }
        return $ret;
    } else {
        $path = rtrim($dirName, '/') . '/';
        $file = new FilesystemIterator($path);
        $ret = array();
        foreach ($file as $fileinfo) {
            $ret[] = $path . $fileinfo->getFilename();
            if ($fileinfo->isDir()) {
                $subdir_arr = file_getlist($path . $fileinfo->getFilename() . '/', true);
                $ret = array_merge($ret, $subdir_arr);
            }
        }

        return $ret;
    }
}

/**
 * 递归创建目录
 * @example  mkdirs('/a/b/c/d');
 */
function file_mkdirs($dir, $mode = 0777)
{
//    echo $dir,'<br>';
//    $dir = parse_document_root($dir);
    if (is_dir($dir) || @mkdir($dir, $mode)) return TRUE;
    if (!@file_mkdirs(dirname($dir), $mode)) return FALSE;

    return @mkdir($dir, $mode);
}


/**
 * 将$content存储到磁盘，并返回md5，下次可以通过该md5提取存储的内容
 * @param $dir
 * @param $content
 * @return string
 */
function saveDataByMd5($dir, $content)
{
    $u = md5($content);
    $u = strtolower($u);

    $left2 = substr($u, 0, 2);
    if (!file_exists($dir . "/{$left2}/{$u}")) {
        @mkdir($dir . "/{$left2}", 0777);
        file_put_contents($dir . "/{$left2}/{$u}", $content);
    }
    return $u;
}

/**根据short获取内容
 * @param $dir
 * @param $md5
 * @return bool|string
 */
function getDataByMd5($dir, $md5)
{
    $u = strtolower($md5);
    $left2 = substr($u, 0, 2);
    $info = "";
    if (file_exists($dir . "/{$left2}/{$u}")) {
        $info = file_get_contents($dir . "/{$left2}/{$u}");
    }
    return $info;
}

/**
 * 压缩核心方法
 * @param $dir string
 * @param $zip ZipArchive
 * @return bool
 */
function zip_addDir2Zip($dir, $zip)
{
    $handler = opendir($dir);
    while (($filename = readdir($handler)) !== false) {
        if ($filename != '.' && $filename != "..") {
            if (is_dir($dir . '/' . $filename)) {// 如果读取的某个对象是文件夹，则递归
                @$zip->addEmptyDir($dir . '/' . $filename);
                zip_addDir2Zip($dir . '/' . $filename, $zip);
                // return '继续压缩';
            } else {
                // 将文件加入zip对象
                @$zip->addFile($dir . '/' . $filename);
                // return '将对象加入压缩文件夹';
            }
        }
    }
    @closedir($dir);
    return true;
}

/**
 * 进行压缩
 * addtime 2020年7月17日 18:02:24
 * @param $dir string 要压缩的目录
 * @param $zipfile string 保存的zip文件
 * @return bool
 */
function zip($dir, $zipfile)
{
    $zip = new \ZipArchive();
    $isopen = $zip->open($zipfile, ZipArchive::CREATE);
    if ($isopen) {
        $nowdir = getcwd();
        @chdir(dirname($dir));
        $dir = file_name($dir);
        $res = zip_addDir2Zip($dir, $zip);
        @$zip->close(); //关闭处理的zip文件
        @chdir($nowdir);
        return $res;
    }
    return false;
}